﻿/// Copyright (c) 2012 John Tear
///
/// Permission is hereby granted, free of charge, to any person obtaining a copy of this software 
/// and associated documentation files (the "Software"), to deal in the Software without restriction, 
/// including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 
/// and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, 
/// subject to the following conditions:
///
/// The above copyright notice and this permission notice shall be included in all copies or substantial 
/// portions of the Software.
///
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT 
/// LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 
/// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 
/// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 
/// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
///

using System;
using System.Collections.Generic;
using System.Text;

namespace com.feelgoodsoftware.sharptftp
{
    /// <summary>
    /// Abstract class to represent a tftp packet.
    /// </summary>
    public abstract class TftpBasePacket
    {
        /// <summary>
        /// Gets the op code of the tftp packet.
        /// </summary>
        public TftpOpCode OpCode { get; set; }

        /// <summary>
        /// Output the contents of the packet in byte form.
        /// </summary>
        /// <returns></returns>
        public abstract byte[] ToByteArray();

        /// <summary>
        /// Factory method that makes a packet from the bytes received on the network wire.
        /// </summary>
        /// <param name="Bytes"></param>
        /// <returns></returns>
        public static TftpBasePacket MakePacket(byte[] Bytes)
        {
            // a valid tftp packet must be at least 4 bytes in length
            if (Bytes.Length < 4)
            {
                // todo: throw a tftp exception
                throw new NotImplementedException();
            }
            else
            {
                // the op code is transmit in byte 1
                switch ((TftpOpCode)Bytes[1])
                {
                    case TftpOpCode.RRQ:
                        return new TftpReadWritePacket(Bytes);
                    case TftpOpCode.WRQ:
                        return new TftpReadWritePacket(Bytes);
                    case TftpOpCode.DATA:
                        return new TftpDataPacket(Bytes);
                    case TftpOpCode.ACK:
                        return new TftpAckPacket(Bytes);
                    case TftpOpCode.ERROR:
                        return new TftpErrorPacket(Bytes);
                    default:
                        // todo: throw a tftp exception
                        throw new NotImplementedException();
                }
            }
        }
    }
}
